#include "opecv_harris.h"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;
 

static Mat g_srcImage, g_srcImage1, g_grayImage;
static int thresh = 30; //当前阈值  
static int max_thresh = 175; //最大阈值  

static void on_CornerHarris(int, void*)
{
	Mat dstImage;//目标图  
	Mat normImage;//归一化后的图  
	Mat scaledImage;//线性变换后的八位无符号整型的图  

	//置零当前需要显示的两幅图，即清除上一次调用此函数时他们的值  
	dstImage = Mat::zeros(g_srcImage.size(), CV_32FC1);
	g_srcImage1 = g_srcImage.clone();

	//进行角点检测  
	//第三个参数表示邻域大小，第四个参数表示Sobel算子孔径大小，第五个参数表示Harris参数
	cornerHarris(g_grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT);

	// 归一化与转换  
	normalize(dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
	convertScaleAbs(normImage, scaledImage);//将归一化后的图线性变换成8位无符号整型   

	// 将检测到的，且符合阈值条件的角点绘制出来  
	for (int j = 0; j < normImage.rows; j++)
	{
		for (int i = 0; i < normImage.cols; i++)
		{
			//Mat::at<float>(j,i)获取像素值，并与阈值比较
			if ((int)normImage.at<float>(j, i) > thresh + 80)
			{
				circle(g_srcImage1, Point(i, j), 5, Scalar(10, 10, 255), 2, 8, 0);
				circle(scaledImage, Point(i, j), 5, Scalar(0, 10, 255), 2, 8, 0);
			}
		}
	}
	
	imshow("harris", g_srcImage1);
	imshow("harris2", scaledImage);

}

void doOpencvHarris1()
{
	g_srcImage = imread("test.jpg", 1);
	if (!g_srcImage.data)
	{
		printf("读取图片错误！ \n");
		return ;
	}
	imshow("src", g_srcImage);
	g_srcImage1 = g_srcImage.clone();

	//存留一张灰度图  
	cvtColor(g_srcImage1, g_grayImage, CV_BGR2GRAY);

	//创建窗口和滚动条  
	namedWindow("harris", CV_WINDOW_AUTOSIZE);
	createTrackbar("thresh: ", "harris", &thresh, max_thresh, on_CornerHarris);

	//调用一次回调函数，进行初始化  
	on_CornerHarris(0, 0);

	waitKey(0);
}


//////////////////////////////////////////////////////////////////////

static Mat src, src_gray;

static int maxCorners = 23;
static int maxTrackbar = 100;

static RNG rng(12345);  //RNG：random number generator，随机数产生器
static char* source_window = "Image";

static void goodFeaturesToTrack_Demo(int, void*)
{
	if (maxCorners < 1) { maxCorners = 1; }

	//初始化 Shi-Tomasi algorithm的一些参数
	vector<Point2f> corners;
	double qualityLevel = 0.01;
	double minDistance = 10;
	int blockSize = 3;
	bool useHarrisDetector = false;
	double k = 0.04;

	//给原图做一次备份
	Mat copy;
	copy = src.clone();

	// 角点检测
	goodFeaturesToTrack(src_gray,corners,maxCorners,qualityLevel,minDistance,Mat(),blockSize,useHarrisDetector,k);

	//画出检测到的角点
	cout << "** Number of corners detected: " << corners.size() << endl;
	int r = 4;
	for (int i = 0; i < corners.size(); i++)
	{
		circle(copy, corners[i], r, Scalar(rng.uniform(0, 255), rng.uniform(0, 255),
			rng.uniform(0, 255)), -1, 8, 0);
	}

	namedWindow(source_window, CV_WINDOW_AUTOSIZE);
	imshow(source_window, copy);
}

void doOpencvHarris2()
{
	//转化为灰度图
	src = imread("test.jpg", 1);
	cvtColor(src, src_gray, CV_BGR2GRAY);

	namedWindow(source_window, CV_WINDOW_AUTOSIZE);

	//创建trackbar
	createTrackbar("MaxCorners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo);

	imshow(source_window, src);

	goodFeaturesToTrack_Demo(0, 0);

	waitKey(0);
}


